var fs = require('fs');
var pattern1 = JSON.parse(fs.readFileSync('./app/logic/sub/YZMJ/huPattern1.json'));
var pattern2 = JSON.parse(fs.readFileSync('./app/logic/sub/YZMJ/huPattern2.json'));
var pattern3 = JSON.parse(fs.readFileSync('./app/logic/sub/YZMJ/huPattern3.json'));
var pattern4 = JSON.parse(fs.readFileSync('./app/logic/sub/YZMJ/huPattern4.json'));
var mapObj = JSON.parse(fs.readFileSync('./app/logic/sub/YZMJ/map1.json'));

var tiles = [
    1, 2, 3, 4, 5, 6, 7, 8, 9, //筒
    11, 12, 13, 14, 15, 16, 17, 18, 19, //条
    21, 22, 23, 24, 25, 26, 27, 28, 29, // 万
    31, 42, 53, 64, 75, 76, 77  //东南西北不能组成顺子，中发白可以组成顺子
]

var choicePattern = {
    "0": pattern1,
    "1": pattern2,
    "2": pattern3,
    "3": pattern4,
}
/*
win 是手牌 类型 [12,13,11,12...]
检查手牌排序是否正确
 */
function checkValid(win) {
    win.sort(function (a, b) {
        return a - b;
    });
    for (var i = 4; i < win.length; ++i) {
        if (win[i] == win[i - 4]) {
            return false;
        }
    }
    return true;
}
/**
 * 检查常规胡牌,赖子也算本字
 * @param {*数组} cards
 * @param {吃碰杠的次数} n
 * @return {boolean}
 */
function checkHuNormal(cards, n) {
    var Pattern = choicePattern[n];

    var turned = turnCards(cards);
    var pattern = codeCards(turned);
    if (Pattern[pattern]) {
        return true;
    }
    return false;
}
/**
 * 
 * @param {*数组,没有赖子} cards 
 * @param {*吃碰杠次数} n 
 * @return {数组,返回赖子替换成某个牌的所有类型}
 */
function hasOneLZ(cards, n) {
    var result = [];
    var Pattern = choicePattern[n];
    var turned = turnCards(cards);
    tiles.forEach(function (v) {
        var temp = turned.slice();
        temp.push(v)
        if (checkValid(temp) && Pattern[codeCards(temp)]) {
            result.push(v);
        }
    });
    return result;
}
/**
 * @param {*} cards 
 * @param {*} n
 * @return {boolean} 是否能胡牌 
 */
function checkhas4(win, hunCard) {
    win.sort(function (a, b) {
        return a - b;
    });
    for (var i = 3; i < win.length; ++i) {
        if (win[i] == win[i - 3] && win[i] == hunCard) {
            return true;
        }
    }
    return false;
}
function isOneLZ(cards, n, isTurned, hunCard) {
    var turned;
    if (isTurned) {
        turned = cards;
    } else {
        turned = turnCards(cards);
    }
    var Pattern = choicePattern[n];
    var len = tiles.length;
    for (var i = 0; i < len; ++i) {
        var temp = turned.slice();
        if (hunCard) {
            var temp2 = turned.slice();
            //console.log(checkhas4(temp2, hunCard));
            if (checkhas4(temp2, hunCard)) {
                return true;
            }
        }
        temp.push(tiles[i])
        if (checkValid(temp) && Pattern[codeCards(temp)]) {
            return true;
        }

    }
    return false;
}
/**
 * 
 * @param {*数组,没有赖子} cards 
 * @param {*吃碰杠次数} n 
 * @return {数组,返回赖子替换成某个牌的所有类型}
 */
function hasTwoLZ(cards, n) {
    var result = [];
    var Pattern = choicePattern[n];
    var turned = turnCards(cards);

    tiles.forEach(function (v1) {
        tiles.forEach(function (v2) {
            var temp = turned.slice();
            temp.push(v1)
            temp.push(v2);
            if (checkValid(temp) && Pattern[codeCards(temp)]) {
                result.push([v1, v2]);
            }
        })
    })
    return result;
}
/**
 * 
 * @param {*} cards 
 * @param {*} n
 * @return {boolean} 是否能胡牌 
 */
function isTwoLZ(cards, n, isTurned, hunCard) {
    var turned;
    if (isTurned) {
        turned = cards;
    } else {
        turned = turnCards(cards);
    }
    var Pattern = choicePattern[n];
    var len = tiles.length;
    for (var i = 0; i < len; ++i) {
        for (var j = 0; j < len; ++j) {
            var temp = turned.slice();
            if (hunCard) {
                var temp2 = turned.slice();
                if (checkhas4(temp2,hunCard)) {
                    return true;
                }
            }
            temp.push(tiles[i])
            temp.push(tiles[j]);
            if (checkValid(temp) && Pattern[codeCards(temp)]) {
                return true;
            }

        }
    }
    return false;
}
/**
 * 
 * @param {*数组,没有赖子} cards 
 * @param {*吃碰杠次数} n 
 * @return {数组,返回赖子替换成某个牌的所有类型}
 */
function hasThreeLZ(cards, n) {
    var result = [];
    var Pattern = choicePattern[n];
    var turned = turnCards(cards);

    tiles.forEach(function (v1) {
        tiles.forEach(function (v2) {
            tiles.forEach(function (v3) {
                var temp = turned.slice();
                if (hunCard) {
                    var temp2 = turned.slice();
                    if (checkhas4(temp2)) {
                        return true;
                    }
                } else {
                    temp.push(v1);
                    temp.push(v2);
                    temp.push(v3);
                    if (checkValid(temp) && Pattern[codeCards(temp)]) {
                        result.push([v1, v2, v3]);
                    }
                }

            });
        })
    });
    return result;;
}
/**
 * 
 * @param {*} cards 
 * @param {*} n
 * @return {boolean} 是否能胡牌 
 */
function isThreeLZ(cards, n, isTurned,hunCard) {
    var Pattern = choicePattern[n];
    var turned;
    if (isTurned) {
        turned = cards;
    } else {
        turned = turnCards(cards);
    }
    var len = tiles.length;
    for (var i = 0; i < len; ++i) {
        for (var j = 0; j < len; ++j) {
            for (var k = 0; k < len; ++k) {
                var temp = turned.slice();
                if (hunCard) {
                    var temp2 = turned.slice();
                    if (checkhas4(temp2,hunCard)) {
                        return true;
                    }
                }
                temp.push(tiles[i]);
                temp.push(tiles[j]);
                temp.push(tiles[k]);
                if (checkValid(temp) && Pattern[codeCards(temp)]) {
                    return true;
                }

            }
        }
    }
    return false;
}
/**
 * 吃碰杠4次，判断胡牌
 * @param {*2个手牌} cards 
 */
function checkHu4(cards, lzNum) {
    if (cards[0] == cards[1]) {
        return 1; //硬胡
    } else if (lzNum > 0) {
        return true;
    }
    return false;
}
/**
 * 将未经转换的牌转换成自定义格式
 * @param {*数组} cards 
 */
function turnCards(cards) {
    var temp = [];
    cards.forEach(function (v) {
        temp.push(mapObj[v]);
    });
    return temp;
}
function turnCard(card) {
    return mapObj[card];
}
/**
 * 将牌编码
 * @param {*数组} cards 
 */
function codeCards(cards) {
    cards.sort(function (a, b) {
        return a - b;
    });
    var nums = 1;
    var str = '';
    for (var i = 1; i < cards.length; ++i) {
        if (cards[i - 1] == cards[i]) {
            nums += 1;

        } else if (cards[i - 1] + 1 == cards[i]) {
            str += nums;
            nums = 1;
        } else {
            str += nums;
            nums = 1;
            str += 0;
        }
    }
    str += nums;
    return str;
}
function checkHunDiao(cards, n, lzNum, lzCard) {
    if(n == 4 && lzNum > 0){
        return true;
    }
    if (lzNum == 0) {
        return false;
    }
    var Pattern = choicePattern[n];
    var count;
    if (lzNum == 1) {
        count = isOneLZ;
    } else if (lzNum == 2) {
        count = isTwoLZ;
    } else if (lzNum == 3) {
        count = isThreeLZ;
    } else {
        count = checkHuNormal;
    }
    var turned = turnCards(cards);
    var flag = true;
    var lzCard = turnCard(lzCard);
    tiles.forEach(function (v) {
        if (v != lzCard) {
            var temp = turned.slice();
            temp.push(v);

            if (count(temp, n, true, v)) {

            } else {
    
                flag = false;
            }
        }
    });
    return flag
}
//项目特殊牌型判断
//===============================
/**
 * 
 * @param {*数组,14张手牌} cards 
 */
function pair7(cards, lzNum, lzCard) {
    if (cards.length != 14) {
        return false;
    }
    var temp = cards.slice();
    temp.sort(function (a, b) {
        return a - b
    })
    var flag = {};
    temp.forEach(function (v) {
        if (!flag[v]) {
            flag[v] = 1;
        } else {
            flag[v] += 1;
        }
    });
 
    var num1 = 0;
    var num4 = 0;
    var num3 = 0;
    var keys = Object.keys(flag);
    keys.forEach(function (v) {

        if (flag[v] == 1) {
            num1 += 1;
        } else if (flag[v] == 3) {
            num1 += 1;
            num3 += 1;
        } else if (flag[v] == 4) {
            num4 += 1;
        }

    });

    if (num1 == 0 && num3 == 0 && num4 > 0) {
        return 2 //豪华七对
    }
    if (num1 == 0 && num3 == 0) {
        return 1//青七对
    }

    var num1 = 0;
    var num4 = 0;
    var num3 = 0;

    keys.forEach(function (v) {
        if (v != lzCard) {
            if (flag[v] == 1) {
                num1 += 1;
            } else if (flag[v] == 3) {
                num1 += 1;
                num3 += 1;
            } else if (flag[v] == 4) {
                num4 += 1;
            }
        }
    });
    if (num1 != 0 && num1 != lzNum) {
        return false;
    }
    return true;
}

module.exports = {
    pair7: pair7,
    checkHu4: checkHu4,
    isThreeLZ: isThreeLZ,
    hasThreeLZ: hasThreeLZ,
    isTwoLZ: isTwoLZ,
    hasTwoLZ: hasTwoLZ,
    isOneLZ: isOneLZ,
    hasOneLZ: hasOneLZ,
    checkHuNormal: checkHuNormal,
    checkHunDiao: checkHunDiao,
    checkhas4:checkhas4
}